package com.gwtapps.messenger.client;

import java.util.ArrayList;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.gwtapps.messenger.client.model.Contact;
import com.gwtapps.messenger.client.model.ContactList;
import com.gwtapps.messenger.client.model.Message;
import com.gwtapps.messenger.client.view.MessengerView;
import com.gwtapps.messenger.client.view.MessengerViewListener;

public class MessengerServiceClientImpl implements MessengerViewListener{
	
	private class SignInCallback implements AsyncCallback<Object>{
		public void onFailure(Throwable throwable){ GWT.log("error sign in",throwable); }
		public void onSuccess(Object obj){
			view.setContactList( contactList );
			view.setMap(contactList);
			messengerService.getEvents( new GetEventsCallback() );
		}
	}
	
	private class EmptyCallback implements AsyncCallback<Object>{
		public void onFailure(Throwable throwable){ GWT.log("error",throwable); }
		public void onSuccess(Object obj){}
	}	
	
	private class GetEventsCallback implements AsyncCallback<Object>{
		public void onFailure(Throwable throwable){ GWT.log("error get events",throwable); }
		@SuppressWarnings("unchecked")
		public void onSuccess(Object obj){
			ArrayList<Object> events = (ArrayList<Object>)obj;
			for( int i=0; i< events.size(); ++i ){
				Object event = events.get(i);
				handleEvent( event );
			}
			messengerService.getEvents( this );
		}
	}

	private MessengerServiceAsync messengerService;
	private ContactList contactList;
	private MessengerView view = new MessengerView( this );

	public MessengerServiceClientImpl( String URL ){
		messengerService = (MessengerServiceAsync) GWT.create( MessengerService.class );
		ServiceDefTarget endpoint = (ServiceDefTarget) messengerService;
		endpoint.setServiceEntryPoint( URL );		
	}

	public MessengerView getView(){
		return view;
	}

	public void onSignIn( String name, int gridx, int gridy, int direction, int charPosOnMapX,
			int charPosOnMapY, int healt  ){
		contactList = new ContactList( name,gridx,gridy,direction,charPosOnMapX,charPosOnMapY,healt );
		messengerService.signIn( name,gridx,gridy,direction,charPosOnMapX,charPosOnMapY,healt, new SignInCallback() );
	}

	public void onSignOut(){
		messengerService.signOut( new EmptyCallback() );
	}
	
	public void onChangeLocation(int newGridx,int newGridy){
		messengerService.changeLocation(newGridx, newGridy, new EmptyCallback() );
	}

	public void onHit(Contact toContact) {
		messengerService.hit(toContact, new EmptyCallback());
	}
	public void onHitOccurred(String hitman,String receiver) {
		messengerService.hitOccurred(hitman, receiver, new EmptyCallback());
	}

	public void onSendMessage( Contact toContact, Message message ){
		messengerService.sendMessage( toContact, message, new EmptyCallback() );
	}

	protected void handleEvent( Object event ){
		if( event instanceof SendMessageEvent ){	
			SendMessageEvent sendMessageEvent = (SendMessageEvent)event;
			view.getChatWindowView( sendMessageEvent.sender ).addMessage( sendMessageEvent.message );
		}
		else if( event instanceof SignOnEvent ){
			SignOnEvent signOnEvent = (SignOnEvent)event;
			contactList.addContact(signOnEvent.contact);
			view.getContactListView().addContact(signOnEvent.contact);
			view.getMapView().addCharacter(signOnEvent.contact);
		}
		else if( event instanceof SignOffEvent ){
			SignOffEvent signOffEvent = (SignOffEvent)event;
			contactList.removeContact(signOffEvent.contact);
			view.getContactListView().removeContact(signOffEvent.contact);
			view.getMapView().removeCharacter(signOffEvent.contact);
		}
		else if( event instanceof ChangeLocationEvent ){
			ChangeLocationEvent changeLocationEvent = (ChangeLocationEvent)event;
			contactList.setGridPosOfContact(changeLocationEvent.contact);
		}
		else if( event instanceof HitEvent ){
			HitEvent hit = (HitEvent)event;
			if(view.getMapView().checkTheHitterPosition(hit.sender.getName())){
				//Hit ocurred by hitter (hit.sender.getName())
				//to me (view.getContactList().getMe().getName();)
				//send broadcast message to all user for animations
				//the messeage included hitter & receiver name.
				//animation for receiver(checker)
				view.getListener().onHitOccurred(hit.sender.getName(), view.getContactList().getMe().getName());
				view.getMapView().allCharacters.get(hit.sender.getName()).characterHitAnimation();
				view.getMapView().allCharacters.get(view.getContactList().getMe().getName()).getDamageAnimation();
			}else{
				//Hit is not occurred
				//send miss message to hitter(hit.sender.getName())
			}
			//Window.alert("hitter: "+hit.sender.getName());
//			check the hitter for hit me
		}
		else if( event instanceof HitOccurredEvent ){/*animasyonları cagır*/
			HitOccurredEvent hitOccurred = (HitOccurredEvent)event;
			view.getMapView().allCharacters.get(hitOccurred.hitman).characterHitAnimation();
			view.getMapView().allCharacters.get(hitOccurred.receiver).getDamageAnimation();
			
		}
	}
}
